/*
 * Reksio - Memory Map Editor
 * Copyright (C) 2023 CERN
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * In applying this licence, CERN does not waive the privileges and immunities
 * granted to it by virtue of its status as an Intergovernmental Organization or
 * submit itself to any jurisdiction.
 */

#ifndef ATTRIBUTE_H
#define ATTRIBUTE_H

#include <string>
#include <vector>
#include <memory>
#include <QMetaType>

class MemoryNode; // fwd declaration
class AttributeContainer; // fwd declaration
class AttributeValidator; // fwd decl

struct INodeRuleValidator;
class Attribute
{
public:
    explicit Attribute(const std::string& name, const std::string& value = "");
    Attribute(const Attribute&) = default;
    bool operator==(const Attribute& rhs) const;
    bool isValid() const;
    const std::string& getValue() const;
    void setValue(const std::string& value);
    void setParent(AttributeContainer* parent);
    AttributeContainer* getParent() const;
    MemoryNode* getParentNode() const;
    const std::string& getName() const;
    std::vector<std::string> getFullName() const;
    std::vector<INodeRuleValidator*> validate();
    AttributeValidator* getValidator() const;
    const std::vector<INodeRuleValidator*>& getFailedValidators() const;

    // misc
    bool isSavable() const;
    void setSavable(bool savable);

    bool isEditable() const;
    void setEditable(bool editable);

    bool isDeprecated() const;

private:
    const std::string _name;
    std::string _value;
    AttributeContainer* _parent = nullptr;
    std::vector<INodeRuleValidator*> failed_validators;
    bool _savable = true; // if item should be saved
    bool _editable = true; // if item can be edited
};

std::ostream& operator<< (std::ostream& stream, const Attribute& attribute);

Q_DECLARE_METATYPE(Attribute*)

#endif // ATTRIBUTE_H
